package com.demo.personalaccountingbackend.service.impl;

import com.demo.personalaccountingbackend.dto.TokenDTO;
import com.demo.personalaccountingbackend.service.TokenService;
import com.demo.personalaccountingbackend.utils.JwtUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
/**
 * 类描述信息
 *
 * @author zgx
 * @version 1.0
 * @date 2025/10/20 15:10
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TokenServiceImpl implements TokenService {

    private final JwtUtil jwtTokenUtil;
    private final RedisTemplate<String, Object> redisTemplate;

    private static final String REDIS_TOKEN_PREFIX = "token:";
    private static final String REDIS_REFRESH_PREFIX = "refresh:";

    @Override
    public TokenDTO createToken(Long userId, String username) {
        // 生成访问令牌和刷新令牌
        String accessToken = jwtTokenUtil.generateToken(username, userId);
        String refreshToken = jwtTokenUtil.generateRefreshToken(username, userId);

        // 将刷新令牌存入Redis
        String refreshKey = REDIS_REFRESH_PREFIX + refreshToken;
        redisTemplate.opsForValue().set(refreshKey, userId.toString(),
                jwtTokenUtil.getRefreshExpirationTime(), TimeUnit.MILLISECONDS);

        return new TokenDTO(accessToken, refreshToken,
                jwtTokenUtil.getExpirationTime(), jwtTokenUtil.getRefreshExpirationTime());
    }

    @Override
    public boolean validateToken(String token) {
        return jwtTokenUtil.validateToken(token);
    }

    @Override
    public String refreshAccessToken(String refreshToken) {
        // 验证刷新令牌是否存在
        String refreshKey = REDIS_REFRESH_PREFIX + refreshToken;
        String userIdStr = (String) redisTemplate.opsForValue().get(refreshKey);

        if (userIdStr == null) {
            throw new RuntimeException("刷新令牌无效或已过期");
        }

        Long userId = Long.parseLong(userIdStr);
        String username = jwtTokenUtil.getUsernameFromToken(refreshToken);

        if (username == null) {
            throw new RuntimeException("刷新令牌解析失败");
        }

        // 生成新的访问令牌
        return jwtTokenUtil.generateToken(username, userId);
    }

    @Override
    public void invalidateToken(String token) {
        // 从刷新令牌中获取信息
        String refreshKey = REDIS_REFRESH_PREFIX + token;
        redisTemplate.delete(refreshKey);
    }

    @Override
    public Long getExpirationTime() {
        return jwtTokenUtil.getExpirationTime();
    }

    @Override
    public Long getRefreshExpirationTime() {
        return jwtTokenUtil.getRefreshExpirationTime();
    }
}
